home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / admin / linuxcon.000 / linuxcon / linuxconf-1.6 / xconf / component.c < prev    next >
C/C++ Source or Header  |  1995-01-12  |  8KB  |  341 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <limits.h>
  4. #include "../misc/misc.h"
  5. #include "xconf.h"
  6. #include "components.h"
  7.  
  8. PUBLIC COMPONENT::COMPONENT(
  9.     const char *manuf_id,
  10.     const char *model_id,
  11.     XCONFIG *_xconfig,
  12.     NOTICE *_notice,
  13.     ACTION *_action)
  14.     : PAIRES (manuf_id,model_id)
  15. {
  16.     xconfig = _xconfig;
  17.     notice = _notice;
  18.     action = _action;
  19. }
  20.  
  21. PUBLIC COMPONENTS::COMPONENTS()
  22. {
  23.     max_component = 0;
  24.     nb_component = 0;
  25.     tb_component = NULL;
  26.     max_xconfig = 0;
  27.     nb_xconfig = 0;
  28.     tb_xconfig = NULL;
  29.     max_notice = 0;
  30.     nb_notice = 0;
  31.     tb_notice = NULL;
  32. }
  33.  
  34. PUBLIC VIRTUAL COMPONENTS::~COMPONENTS()
  35. {
  36.     for (int i=0; i<nb_component; i++) delete tb_component[i];
  37.     free (tb_component);
  38.     for (i=0; i<nb_xconfig; i++) delete tb_xconfig[i];
  39.     free (tb_xconfig);
  40.     for (i=0; i<nb_notice; i++) delete tb_notice[i];
  41.     free (tb_notice);
  42. }
  43.  
  44. /*
  45.     Add a new component to the list
  46. */
  47. PUBLIC void COMPONENTS::add (COMPONENT *comp)
  48. {
  49.     if (nb_component == max_component){
  50.         max_component += 50;
  51.         tb_component = (COMPONENT**)realloc(tb_component
  52.             ,sizeof(XCONFIG*)*max_component);
  53.     }
  54.     tb_component[nb_component++] = comp;
  55. }
  56. /*
  57.     Add a new partial Xconfig to the list
  58. */
  59. PUBLIC void COMPONENTS::add (XCONFIG *xconf)
  60. {
  61.     if (nb_xconfig == max_xconfig){
  62.         max_xconfig += 10;
  63.         tb_xconfig = (XCONFIG**)realloc(tb_xconfig
  64.             ,sizeof(XCONFIG*)*max_xconfig);
  65.     }
  66.     tb_xconfig[nb_xconfig++] = xconf;
  67. }
  68. /*
  69.     Add a new notice to the list
  70. */
  71. PUBLIC void COMPONENTS::add (NOTICE *notice)
  72. {
  73.     if (nb_notice == max_notice){
  74.         max_notice += 10;
  75.         tb_notice = (NOTICE**)realloc(tb_notice
  76.             ,sizeof(NOTICE*)*max_notice);
  77.     }
  78.     tb_notice[nb_notice++] = notice;
  79. }
  80.  
  81. /*
  82.     Read and parse a xconf file
  83. */
  84. PUBLIC int COMPONENTS::read (const char *fname)
  85. {
  86.     int ret = -1;
  87.     FILE *fin = xconf_fopen (fname,"r");
  88.     if (fin != NULL){
  89.         char buf[300];
  90.         ret = 0;
  91.         XCONFIG *xconfig = NULL;
  92.         NOTICE *notice = NULL;
  93.         ACTION *action = NULL;
  94.         char manuf[100];
  95.         manuf[0] = '\0';
  96.         char doing_xconfig = 0;    // Parsing between @ paires ?
  97.         char doing_notice = 0;    // Parsing between ! paires ?
  98.         char doing_action = 0;    // Parsing between $ paires ?
  99.         int noline = 0;
  100.         while (fgets(buf,sizeof(buf)-1,fin)!= NULL){
  101.             noline++;
  102.             str_strip (buf,buf);
  103.             /* #Specification: data files / *.xconf
  104.                 file *.xconf are lists of hardware components
  105.                 (either screen or adaptor). The format is simple
  106.                 although not so visual.
  107.  
  108.                 -manufacturer ID
  109.                     @
  110.                         parts of an Xconfig file useful for the
  111.                         next component model following this section
  112.                     @
  113.                     model ID
  114.                     Another model sharing the same configuration
  115.                     @
  116.                         A different Xconfig setup
  117.                     @
  118.                     !
  119.                         A notice applying to following component
  120.                         The notice hold true until a new notice
  121.                         is entered.
  122.                     !
  123.                     $
  124.                         A script to execute to make the configuration
  125.                         effective. The script will be valid for
  126.                         all following model
  127.                     $
  128.                     another model ID
  129.                 -another manufacturer
  130.  
  131.                 Note also that the configurator merge several *.xconf files.
  132.                 For example, I expect that a *.xconf file will be bundle
  133.                 with each specific X server available (Mach32 SVGA etc...)
  134.  
  135.                 Here is a small example
  136.  
  137.                 -ATI
  138.                     @
  139.                         ACCEL
  140.                             Clocks   100.0 126.0 92.4 36.0 50.35 56.64 0 44.90
  141.                                  135.0 32.0 110.0 80.0 39.91 49.90 75.0 65.0 
  142.                             Option "sw_cursor"
  143.                             Modes "1024x768"
  144.                     @
  145.                     $
  146.                         ln -sf /usr/X11R6/bin/XF86_Mach32 /usr/X11R6/bin/X
  147.                     $
  148.                     vlb Mach32
  149.                     !
  150.                         Please note that the busmouse on the Mach8 and Mach32
  151.                         has to be configurer on IRQ 5.
  152.                     !
  153.                     Mach32 ultra
  154.                     !
  155.                     !
  156.                 -Genoa
  157.                     .
  158.                     .                        
  159.  
  160.                 Line beginning with a # is a comment. Empty lines are
  161.                 allowed.
  162.             */
  163.             /* #Specification: data files / *.xconf / order
  164.                 There is no need to put all products of a manufacturer
  165.                 in the same section. Xconfigs may appear anywhere
  166.                 and are shared between manufacturer. The following is
  167.                 valid.
  168.  
  169.                 @
  170.                     long Xconfig configuration
  171.                     .
  172.                 @
  173.                 -manuf1
  174.                     model1
  175.                     model2
  176.                 -manuf2
  177.                     model4
  178.                 @
  179.                     other long configuration
  180.                 @
  181.                 -manuf1
  182.                     model3
  183.             */
  184.             char *pt = buf;
  185.             while (isspace (*pt)) pt++;
  186.             if (pt[0] != '#' && pt[0] != '\0'){
  187.                 if (pt[0] == '-'){
  188.                     pt++;
  189.                     while (isspace(*pt)) pt++;
  190.                     strcpy (manuf,pt);
  191.                 }else if (pt[0] == '@'){
  192.                     if (doing_xconfig){
  193.                         doing_xconfig = 0;
  194.                     }else{
  195.                         doing_xconfig = 1;
  196.                         xconfig = new XCONFIG;
  197.                         add (xconfig);
  198.                     }
  199.                 }else if (pt[0] == '!'){
  200.                     if (doing_notice){
  201.                         doing_notice = 0;
  202.                     }else if (pt[1] == '!'){
  203.                         /* #Specification: data files / *.xconf / null notice
  204.                             A line with !! indicate a null notice until
  205.                             a new one is seen.
  206.  
  207.                             A line with $$ indicate a null action
  208.                         */
  209.                         notice = NULL;
  210.                     }else{
  211.                         doing_notice = 1;
  212.                         notice = new NOTICE;
  213.                         add (notice);
  214.                     }
  215.                 }else if (pt[0] == '$'){
  216.                     if (doing_action){
  217.                         doing_action = 0;
  218.                     }else if (pt[1] == '$'){
  219.                         action = NULL;
  220.                     }else{
  221.                         doing_action = 1;
  222.                         action = new ACTION;
  223.                         add (action);
  224.                     }
  225.                 }else if (doing_xconfig){
  226.                     xconfig->parse (buf,fname,noline);
  227.                 }else if (doing_notice){
  228.                     notice->add (pt);
  229.                 }else if (doing_action){
  230.                     action->add (pt);
  231.                 }else{
  232.                     // This is a model ID
  233.                     add (new COMPONENT (manuf,pt,xconfig,notice,action));
  234.                 }
  235.             }
  236.         }
  237.         fclose (fin);
  238.     }
  239.     return ret;
  240. }
  241. static int cmp (const void **pp1, const char **pp2)
  242. {
  243.     COMPONENT *p1 = (COMPONENT *)(*pp1);
  244.     COMPONENT *p2 = (COMPONENT *)(*pp2);
  245.     int ret = strcmp(p1->keyw,p2->keyw);
  246.     if (ret == 0) ret = strcmp(p1->arg,p2->arg);
  247.     return ret;
  248. }
  249. /*
  250.     Sort all COMPONENT by manuf_id and model_id.
  251. */
  252. PUBLIC void COMPONENTS::sort ()
  253. {
  254.     qsort (tb_component,nb_component,sizeof(COMPONENT*),cmp);
  255. }
  256.  
  257. /*
  258.     Print all COMPONENTS with the same format as input, mostly to debug
  259. */
  260. PUBLIC void COMPONENTS::print (FILE *fout)
  261. {
  262.     XCONFIG *xconfig=NULL;
  263.     NOTICE *notice=NULL;
  264.     ACTION *action=NULL;
  265.     char manuf[100];
  266.     manuf[0] = '\0';
  267.     for (int i=0; i<nb_component; i++){
  268.         COMPONENT *comp = tb_component[i];
  269.         if (strcmp(comp->keyw,manuf)!=0){
  270.             strcpy (manuf,comp->keyw);
  271.             fprintf (fout,"-%s\n",manuf);
  272.         }
  273.         if (comp->xconfig != xconfig){
  274.             xconfig = comp->xconfig;
  275.             fprintf (fout,"\t@\n");
  276.             xconfig->print (fout,2);
  277.             fprintf (fout,"\t@\n");
  278.         }
  279.         if (comp->notice != notice){
  280.             notice = comp->notice;
  281.             fprintf (fout,"\t!\n");
  282.             notice->print (fout,2);
  283.             fprintf (fout,"\t!\n");
  284.         }
  285.         if (comp->action != action){
  286.             action = comp->action;
  287.             fprintf (fout,"\t$\n");
  288.             action->print (fout,2);
  289.             fprintf (fout,"\t$\n");
  290.         }
  291.         fprintf (fout,"\t%s\n",comp->arg);
  292.     }
  293. }
  294.  
  295. /*
  296.     Encode de component ids in a string table so it fit the dialog system.
  297.     tb[optnum*2] = manuf_id;
  298.     tb[optnum*2+1] = model_id;
  299.  
  300.     Return the number of components placed in tbopt2, not the number of
  301.     strings.
  302. */
  303. PUBLIC int COMPONENTS::setmenu (
  304.     char *tbopt2[])
  305. {
  306.     int nb = 0;
  307.     char *manuf = NULL;
  308.     for (int i=0; i<nb_component; i++){
  309.         COMPONENT *comp = tb_component[i];
  310.         if (manuf == NULL || strcmp(comp->keyw,manuf)!=0){
  311.             manuf = comp->keyw;
  312.             tbopt2[nb++] = manuf;
  313.         }else{
  314.             tbopt2[nb++] = " ";
  315.         }
  316.         tbopt2[nb++] = comp->arg;
  317.     }
  318.     tbopt2[nb] = NULL;
  319.     return nb_component;
  320. }
  321.  
  322. PUBLIC COMPONENT *COMPONENTS::item(int no)
  323. {
  324.     COMPONENT *ret = NULL;
  325.     if (no >= 0 && no < nb_component) ret = tb_component[no];
  326.     return ret;
  327. }
  328. #ifdef TEST
  329.  
  330. int main (int argc, char *argv[])
  331. {
  332.     COMPONENTS comp;
  333.     comp.read ("adaptors.xconf");
  334.     comp.sort ();
  335.     comp.print (stdout);
  336.     return 0;
  337. }
  338.  
  339. #endif
  340.  
  341.